package com.sinobpo.rnd2.ehr.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.sinobp.rnd2.ehr.dao.MedSatDaoTest;
import com.sinobpo.rnd2.ehr.model.ClinicSat;
import com.sinobpo.rnd2.ehr.model.HosNumSat;
import com.sinobpo.rnd2.ehr.model.MedExpSat;

/**
 * 通用帮助类
 * 
 * @author yinghui.zhang
 * @CreateDate 2012-7-15
 * @file CommonUtil.java
 * @package com.sinobpo.rnd2.ehr.util
 * @version 1.0
 * @Email uuhui@163.com
 */
public class CommonUtil {
	/**
	 * 设置饼图的数据格式
	 * 
	 * @param obj
	 *            数据数组
	 * @return List<String>
	 */
	public static List<String> getPieChartData(Object[] obj,
			PieDataType pieDataType) {
		List<String> list = new ArrayList<String>();
		switch (pieDataType) {
		case ClininNumcPie: {// 门诊量统计
			list.add("{name:'急诊',y:" + obj[1] + "}");
			list
					.add("{name:'门诊' ,y:" + obj[0]
							+ ",sliced: true,selected:true}");
			break;
		}
		case HosNumPie:// 住院量统计
		{
			list.add("{name:'出院数',y:" + obj[1] + "}");
			// list.add("{name:'在院数',y:" + obj[2] + "}");
			list.add("{name:'入院数' ,y:" + obj[0]
					+ ",sliced: true,selected:true}");
			break;
		}
		case SatTypePie: {// 统计类型
			list.add("{name:'门诊',y:" + obj[1] + "}");
			list
					.add("{name:'住院' ,y:" + obj[0]
							+ ",sliced: true,selected:true}");
			break;
		}
		case MedExpTypePie: {// 病人类型
			list.add("{name:'自费',y:" + obj[0] + "}");
			if (obj.length == 2)
				list.add("{name:'医保' ,y:" + obj[1]
						+ ",sliced: true,selected:true}");
			if (obj.length == 3)
				list.add("{name:'合保',y:" + obj[2] + "}");
			break;
		}
		case PatientPie: {// 费用类型{
			list.add("{name:'诊疗',y:" + obj[0] + "}");
			if (obj.length == 2)
				list.add("{name:'药品' ,y:" + obj[1]
						+ ",sliced: true,selected:true}");
			if (obj.length == 3)
				list.add("{name:'其它',y:" + obj[2] + "}");
		}
		}
		return list;
	}

	/**
	 * 设置门诊图表的数据格式
	 * 
	 * @param timeType
	 *            日期格式[年/月/日]
	 * @param list
	 *            对象集合
	 * @return Map<String,Object>
	 */
	public static Map<String, Object> getChartOfClinicSatData(
			TimeType timeType, List<ClinicSat> list) {
		Map<String, Object> map = new HashMap<String, Object>();// map集合
		Map<String, Object> opsMap = new HashMap<String, Object>();// 门诊Map集合
		Map<String, Object> emMap = new HashMap<String, Object>();// 急诊Map集合
		List<String> categoriesList = new ArrayList<String>();// xAxis(x轴)集合
		List<Integer> opsDataLit = new ArrayList<Integer>();// 门诊数据集合
		List<Integer> emDataList = new ArrayList<Integer>();// 急诊数据集合
		String[] days = null;
		for (ClinicSat clinicSat : list) {
			switch (timeType) {
			case DAY:
				days = clinicSat.getRepDate().split("-");
				categoriesList.add(days[1] + "." + days[2].substring(0, 2));
				break;

			case MONTH:
			case YEAR:
				categoriesList.add(clinicSat.getRepDate());
				break;
			}
			opsDataLit.add(clinicSat.getOpsNum());
			emDataList.add(clinicSat.getEmergencyNum());
		}
		opsMap.put("name", "门诊");
		opsMap.put("data", opsDataLit);
		emMap.put("name", "急诊");
		emMap.put("data", emDataList);
		List<Object> seriesLit = new ArrayList<Object>();
		seriesLit.add(emMap);
		seriesLit.add(opsMap);
		map.put("categories", categoriesList);
		map.put("series", seriesLit);
		return map;
	}

	/**
	 * 设置住院人数统计图表的数据格式
	 * 
	 * @param timeType
	 *            日期格式[年/月/日]
	 * @param list
	 *            对象集合
	 * @return Map<String,Object>
	 */
	public static Map<String, Object> getChartOfHosNumSatData(
			TimeType timeType, List<HosNumSat> list) {
		Map<String, Object> map = new HashMap<String, Object>();// map集合
		Map<String, Object> inHosNumMap = new HashMap<String, Object>();// 当天入院人数Map集合
		Map<String, Object> outHosNumMap = new HashMap<String, Object>();// 当天出院人数Map集合
		// Map<String, Object> totalHosNumMap = new HashMap<String, Object>();//
		// 当天在院人数集合
		List<String> categoriesList = new ArrayList<String>();// xAxis(x轴)集合
		List<Integer> inHosNumLit = new ArrayList<Integer>();// 当天入院人数数据集合
		List<Integer> outHosNumList = new ArrayList<Integer>();// 当天出院人数数据集合
		List<Integer> totalHostNumList = new ArrayList<Integer>();// 当天在院人数数据集合
		String[] days = null;
		for (HosNumSat hosNumSat : list) {
			switch (timeType) {
			case DAY:
				days = hosNumSat.getRepDate().split("-");
				categoriesList.add(days[1] + "." + days[2].substring(0, 2));
				break;
			case MONTH:
			case YEAR:
				categoriesList.add((String) hosNumSat.getRepDate());
				break;
			}
			inHosNumLit.add(hosNumSat.getInHosNum());
			outHosNumList.add(hosNumSat.getOutHosNum());
			totalHostNumList.add(hosNumSat.getTotalNum());
		}
		inHosNumMap.put("name", "入院数");
		inHosNumMap.put("data", inHosNumLit);
		outHosNumMap.put("name", "出院数");
		outHosNumMap.put("data", outHosNumList);
		// totalHosNumMap.put("name", "在院数");
		// totalHosNumMap.put("data", totalHostNumList);
		List<Object> seriesLit = new ArrayList<Object>();
		seriesLit.add(outHosNumMap);
		seriesLit.add(inHosNumMap);
		// seriesLit.add(totalHosNumMap);
		map.put("categories", categoriesList);
		map.put("series", seriesLit);
		return map;
	}

	/**
	 * 设置医疗费用统计图表的数据格式
	 * 
	 * @param satType
	 *            统计类型[门诊/住院]
	 * @param patientType
	 *            病人类型
	 * @param medExpType
	 *            费用类型
	 * @param medExpType
	 *            医疗费用枚举类型
	 * @param timeType
	 *            日期枚举类型[年/月/日]
	 * @param list
	 *            对象集合
	 * @return Map<String,Object>
	 */
	public static Map<String, Object> getChartOfMedExpSatData(String satType,
			String patientType, String medExpType, MedExpSatType medExpSatType,
			TimeType timeType, List<MedExpSat> list) {
		Map<String, Object> map = new HashMap<String, Object>();// map集合
		List<String> categoriesList = new ArrayList<String>();// xAxis(x轴)集合
		Map<String, List<MedExpSat>> satMap = null;// 统计数据Map 集合
		List<Object> seriesLit = new ArrayList<Object>();
		List<Map<String, List<MedExpSat>>> mapList = getMedExpData(patientType,
				medExpType, list);
		if (mapList.size() > 0)
			satMap = mapList.get(0);
		Map<String, String> categoriesMap = new HashMap<String, String>();
		String[] days = null;
		for (MedExpSat medExpSat : list) {
			switch (timeType) {
			case DAY:
				days = medExpSat.getRepDate().split("-");
				categoriesMap.put(days[1] + "." + days[2].substring(0, 2),
						days[1] + "." + days[2].substring(0, 2));
				break;

			case MONTH:
			case YEAR:
				categoriesMap.put(medExpSat.getRepDate(), medExpSat
						.getRepDate());
				break;
			}
		}
		for (Iterator<String> it = categoriesMap.values().iterator(); it
				.hasNext();) {
			categoriesList.add((String) it.next());
		}
		if (categoriesList.size() > 1)
			Collections.sort(categoriesList);
		switch (medExpSatType) {
		case MedExpSat: {// 按费用汇总病人类型的数据
			Map<String, Object> ownExpMap = new HashMap<String, Object>();// 自费Map集合
			Map<String, Object> medicalInsuranceMap = new HashMap<String, Object>();// 医保Map集合
			Map<String, Object> farmersInsuranceMap = new HashMap<String, Object>();// 农保Map集合
			ownExpMap.put("name", "自费");
			medicalInsuranceMap.put("name", "医保");
			farmersInsuranceMap.put("name", "合保");
			if (satMap == null) {
				ownExpMap.put("data", "[]");
				medicalInsuranceMap.put("data", "[]");
				farmersInsuranceMap.put("data", "[]");
			} else {
				List<Object> medicalInsuranceList = new ArrayList<Object>();
				List<Object> farmersInsuranceList = new ArrayList<Object>();
				List<Object> ownExpList = new ArrayList<Object>();
				if (satMap.get(MedExpSatType.OwnExp.getValue()) != null) {
					for (MedExpSat medExpSat : satMap.get(MedExpSatType.OwnExp
							.getValue()))
						ownExpList.add(medExpSat.getExpCount());
					ownExpMap.put("data", ownExpList);
					seriesLit.add(ownExpMap);
				}
				if (satMap.get(MedExpSatType.MedicalInsurance.getValue()) != null) {
					for (MedExpSat medExpSat : satMap
							.get(MedExpSatType.MedicalInsurance.getValue()))
						medicalInsuranceList.add(medExpSat.getExpCount());
					medicalInsuranceMap.put("data", medicalInsuranceList);
					seriesLit.add(medicalInsuranceMap);
				}
				if (satMap.get(MedExpSatType.FarmersInsurance.getValue()) != null) {
					for (MedExpSat medExpSat : satMap
							.get(MedExpSatType.FarmersInsurance.getValue()))
						farmersInsuranceList.add(medExpSat.getExpCount());
					farmersInsuranceMap.put("data", farmersInsuranceList);
					seriesLit.add(farmersInsuranceMap);
				}
			}

			break;
		}
		case PatientSat: {// 按病人类型汇总费用类型的数据
			Map<String, Object> diagExpMap = new HashMap<String, Object>();// 诊疗Map集合
			Map<String, Object> drugExpMap = new HashMap<String, Object>();// 药品Map集合
			Map<String, Object> otherExpMap = new HashMap<String, Object>();// 其它Map集合
			List<Object> diagExpList = new ArrayList<Object>();
			List<Object> drugExpList = new ArrayList<Object>();
			List<Object> otherExpList = new ArrayList<Object>();
			// 诊疗费用名称
			diagExpMap.put("name", "诊疗");
			// 药品费用名称
			drugExpMap.put("name", "药品");
			// 其它费用名称
			if (satMap.get(MedExpSatType.OtherExp.getValue()) != null)
				otherExpMap.put("name", "其它");
			if (satMap == null) {
				diagExpMap.put("data", "[]");
				drugExpMap.put("data", "[]");
				otherExpMap.put("data", "[]");

			} else {
				if (satMap.get(MedExpSatType.DiagExp.getValue()) != null) {
					for (MedExpSat medExpSat : satMap.get(MedExpSatType.DiagExp
							.getValue()))
						// 诊疗费用数据
						diagExpList.add(medExpSat.getExpCount());
					diagExpMap.put("data", diagExpList);
					seriesLit.add(diagExpMap);
				}
				if (satMap.get(MedExpSatType.DrugExp.getValue()) != null) {
					for (MedExpSat medExpSat : satMap.get(MedExpSatType.DrugExp
							.getValue()))
						// 药品费用数据
						drugExpList.add(medExpSat.getExpCount());
					drugExpMap.put("data", drugExpList);
					seriesLit.add(drugExpMap);
				}
				if (satMap.get(MedExpSatType.OtherExp.getValue()) != null) {
					for (MedExpSat medExpSat : satMap
							.get(MedExpSatType.OtherExp.getValue()))
						// 其它费用数据
						otherExpList.add(medExpSat.getExpCount());
					otherExpMap.put("data", otherExpList);
					seriesLit.add(otherExpMap);
				}
			}

			break;
		}
		}
		map.put("categories", categoriesList);
		map.put("series", seriesLit);
		return map;
	}

	/**
	 * 根据费用类型生成医疗费用数据集合信息 包括(诊疗/药品/其它)
	 * 
	 * @param patientType
	 *            病人类型[自费/医保/农保]
	 * @param medExpType
	 *            费用类型[诊疗/药品/其它]
	 * @param list
	 * @return Map<String,List<MedExpSat>
	 */
	private static List<Map<String, List<MedExpSat>>> getMedExpData(
			String patientType, String medExpType, List<MedExpSat> list) {
		List<Map<String, List<MedExpSat>>> listMap = new ArrayList<Map<String, List<MedExpSat>>>();// list集合
		// 病人类型Map集合
		Map<String, List<MedExpSat>> patientMap = new HashMap<String, List<MedExpSat>>();
		// 费用类型Map集合
		Map<String, List<MedExpSat>> medExpMap = new HashMap<String, List<MedExpSat>>();
		// )
		List<MedExpSat> diagExpList = new ArrayList<MedExpSat>();// 诊疗费用集合
		List<MedExpSat> drugExpList = new ArrayList<MedExpSat>();// 药品费用集合
		List<MedExpSat> otherExpList = new ArrayList<MedExpSat>();// 其它费用
		List<MedExpSat> ownExpList = new ArrayList<MedExpSat>();// 自费病人类型集合
		List<MedExpSat> medicalInsuranceList = new ArrayList<MedExpSat>();// 医保病人类型集合
		List<MedExpSat> farmersInsuranceList = new ArrayList<MedExpSat>();// 农保病人类型集合

		for (MedExpSat medExpSat : list) {
			if (patientType != null) {// 按病人类型进行组装数据
				// 设置费用类型集合信息
				if (medExpSat.getEtype().equals(
						MedExpSatType.DiagExp.getValue())) {// 诊疗类型的费用
					diagExpList.add(medExpSat);
				} else if (medExpSat.getEtype().equals(
						MedExpSatType.DrugExp.getValue())) {// 药品类型的费用
					drugExpList.add(medExpSat);
				} else if (medExpSat.getEtype().equals(
						MedExpSatType.OtherExp.getValue())) {// 其它类型的费用
					otherExpList.add(medExpSat);
				}
			} else {// 按费用类型进行组装数据
				// 设置病人类型集合信息
				if (medExpSat.getPtype()
						.equals(MedExpSatType.OwnExp.getValue())) {// 自费类型的病人
					ownExpList.add(medExpSat);
				} else if (medExpSat.getPtype().equals(
						MedExpSatType.MedicalInsurance.getValue())) {// 医保类型的病人
					medicalInsuranceList.add(medExpSat);
				} else if (medExpSat.getPtype().equals(
						MedExpSatType.FarmersInsurance.getValue())) {// 农保类型的病人
					farmersInsuranceList.add(medExpSat);
				}
			}
		}
		if (patientType != null) {
			if (diagExpList.size() != 0)// diagExpList集合内容不为空
				medExpMap.put(MedExpSatType.DiagExp.getValue(), diagExpList);// 添加诊疗类型的费用集合
			if (drugExpList.size() != 0)// drugExpList集合内容不为空
				medExpMap.put(MedExpSatType.DrugExp.getValue(), drugExpList);// 添加药品类型的费用集合
			if (otherExpList.size() != 0)// otherExpList集合内容不为空
				medExpMap.put(MedExpSatType.OtherExp.getValue(), otherExpList);// 添加其它类型的费用集合

		} else {
			if (ownExpList.size() != 0)// ownExpList集合内容不为空
				patientMap.put(MedExpSatType.OwnExp.getValue(), ownExpList);// 添加自费类型的病人集合
			if (medicalInsuranceList.size() != 0)// medicalInsuranceList集合内容不为空
				patientMap.put(MedExpSatType.MedicalInsurance.getValue(),
						medicalInsuranceList);// 添加医保类型的病人集合
			if (farmersInsuranceList.size() != 0)// farmersInsuranceList集合不为空时
				patientMap.put(MedExpSatType.FarmersInsurance.getValue(),
						farmersInsuranceList);// 添加农保类型的病人集合
		}
		if (!patientMap.isEmpty())
			listMap.add(patientMap);
		if (!medExpMap.isEmpty())
			listMap.add(medExpMap);
		return listMap;
	}

	/**
	 * 设置医疗人均费用统计图表的数据格式
	 * 
	 * @param timeType
	 *            日期枚举类型[年/月/日]
	 * @param list
	 *            对象集合
	 * @return Map<String,Object>
	 */
	public static Map<String, Object> getChartOfPCTMedExpSatData(
			TimeType timeType, List<MedExpSat> list) {
		Map<String, Object> map = new HashMap<String, Object>();// map集合
		List<String> categoriesList = new ArrayList<String>();// xAxis(x轴)集合
		Map<String, List<MedExpSat>> satMap = getMedExpDataOfPCT(list);// 统计数据Map
		List<Object> seriesLit = new ArrayList<Object>();
		String[] days = null;
		List<MedExpSat> diagList = satMap.get(MedExpSatType.DiagExp.getValue());// 诊疗集合数据
		List<MedExpSat> drugList = satMap.get(MedExpSatType.DrugExp.getValue());// 药品集合数据
		List<MedExpSat> otherList = satMap.get(MedExpSatType.OtherExp
				.getValue());// 其它费用集合数据
		List<MedExpSat> medExpSatList = null;
		if (diagList.size() >= drugList.size())

			medExpSatList = diagList;
		else
			medExpSatList = drugList;

		for (MedExpSat medExpSat : medExpSatList) {
			switch (timeType) {
			case DAY:
				days = medExpSat.getRepDate().split("-");
				categoriesList.add(days[1] + "." + days[2].substring(0, 2));
				break;
			case MONTH:
			case YEAR:
				categoriesList.add(medExpSat.getRepDate());
				break;
			}
		}
		if (categoriesList.size() > 1)
			Collections.sort(categoriesList);
		// 按费用汇总病人类型的数据
		Map<String, Object> diagExpMap = new HashMap<String, Object>();// 诊疗Map集合
		Map<String, Object> drugExpMap = new HashMap<String, Object>();// 药品Map集合
		Map<String, Object> otherExpMap = new HashMap<String, Object>();// 其它费用Map集合
		List<Double> diagExpList = new ArrayList<Double>();// 诊疗费用集合数据
		diagExpMap.put("name", "诊疗");
		// 诊疗费用数据
		for (MedExpSat medExpSat : diagList)
			diagExpList.add(medExpSat.getExpPCTCount());
		diagExpMap.put("data", diagExpList);
		seriesLit.add(diagExpMap);
		// 药品费用数据
		if (drugList != null && drugList.size() > 0) {
			drugExpMap.put("name", "药品");
			List<Double> drugExpList = new ArrayList<Double>();// 药品费用集合数据
			for (MedExpSat medExpSat : drugList)
				drugExpList.add(medExpSat.getExpPCTCount());
			drugExpMap.put("data", drugExpList);
			seriesLit.add(drugExpMap);
		}
		// 其它费用数据
		if (otherList != null && otherList.size() > 0) {
			otherExpMap.put("name", "其它");
			List<Double> otherExpList = new ArrayList<Double>();// 其它费用集合数据
			for (MedExpSat medExpSat : otherList)
				otherExpList.add(medExpSat.getExpPCTCount());
			otherExpMap.put("data", otherExpList);
			seriesLit.add(otherExpMap);
		}
		map.put("categories", categoriesList);
		map.put("series", seriesLit);
		return map;
	}

	/**
	 * 根据费用类型生成医疗人均费用数据集合信息 包括(诊疗/药品/其它)
	 * 
	 * @param patientType
	 *            病人类型[自费/医保/合保]
	 * @param medExpType
	 *            费用类型[诊疗/药品/其它]
	 * @param list
	 * @return Map<String,List<MedExpSat>
	 */
	private static Map<String, List<MedExpSat>> getMedExpDataOfPCT(
			List<MedExpSat> list) {
		// 费用类型Map集合
		Map<String, List<MedExpSat>> medExpMap = new HashMap<String, List<MedExpSat>>();
		List<MedExpSat> diagExpList = new ArrayList<MedExpSat>();// 诊疗集合
		List<MedExpSat> drugExpList = new ArrayList<MedExpSat>();// 药品集合
		List<MedExpSat> otherExpList = new ArrayList<MedExpSat>();// 其它费用集合
		for (MedExpSat medExpSat : list) {
			// 设置费用类型集合信息
			if (medExpSat.getEtype().equals(MedExpSatType.DiagExp.getValue())) {// 诊疗类型的费用
				diagExpList.add(medExpSat);
			} else if (medExpSat.getEtype().equals(MedExpSatType.DrugExp.getValue())) {// 药品类型的费用
					drugExpList.add(medExpSat);
			} else if (medExpSat.getEtype().equals(MedExpSatType.OtherExp.getValue())) {// 药品类型的费用
				otherExpList.add(medExpSat);
			}
		}
		if (diagExpList.size() != 0)// diagExpList集合内容不为空
			medExpMap.put(MedExpSatType.DiagExp.getValue(), diagExpList);// 添加诊疗类型的费用集合
		if (drugExpList.size() != 0)// drugExpList集合内容不为空
			medExpMap.put(MedExpSatType.DrugExp.getValue(), drugExpList);// 添加药品类型的费用集合
		if (drugExpList.size() != 0)// drugExpList集合内容不为空
			medExpMap.put(MedExpSatType.OtherExp.getValue(), otherExpList);// 添加其它类型的费用集合
		return medExpMap;
	}

	/**
	 * 加载xml文档信息
	 * 
	 * @param xmlFilePath
	 * @return
	 */
	private static Document parse2Document(String xmlFilePath) {
		SAXReader reader = new SAXReader();
		Document document = null;
		try {

			InputStream in = CommonUtil.class.getResourceAsStream(xmlFilePath);
			document = reader.read(in);
		} catch (DocumentException e) {
			System.out.println(e.getMessage());
			System.out
					.println("读取classpath下xmlFileName文件发生异常，请检查CLASSPATH和文件名是否存在！");
			e.printStackTrace();
		}
		return document;
	}

	/**
	 * 解析xml文档信息
	 * 
	 * @param isSort
	 *            是否要排序
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> parseXml(boolean isSort) {
		Document document = parse2Document("/org.xml");
		Element root = document.getRootElement();
		Map<String, String> map = new HashMap<String, String>();
		// 遍历根节点下的节点
		Element element = null;
		for (Iterator<Element> i = root.elementIterator(); i.hasNext();) {
			element = (Element) i.next();
			if (isSort)
				map.put(element.elementText("code") + "-"
						+ element.elementText("order"), element
						.elementText("name"));
			else
				map.put(element.elementText("code"), element
						.elementText("name"));

		}
		return map;
	}

	/**
	 * 对hamMap按key进行排序
	 * 
	 * @param list
	 *            list集体
	 */
	public static void mapSort(List<Entry<String, String>> list) {
		Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
			public int compare(Map.Entry<String, String> o1,
					Map.Entry<String, String> o2) {
				return o1.getKey().split("-")[1].compareTo(o2.getKey().split(
						"-")[1]);
			}
		});
	}

	/**
	 * 将List集合中的Map集合中的key,value值添加到List集合中
	 * 
	 * @param mapList
	 *            list集合
	 * @return List<String>
	 */
	public static List<String> getListFromMaq(
			List<Entry<String, String>> mapList) {
		List<String> list = new ArrayList<String>();
		for (Entry<String, String> e : mapList) {
			list.add("{key:" + e.getKey() + ",value:" + e.getValue() + "}");
		}
		return list;
	}

}
